package vu.alfonsodiecko.stundenplanfhjena.gui;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.holoeverywhere.widget.ProgressBar;

import vu.alfonsodiecko.stundenplanfhjena.OnlineHelper;
import vu.alfonsodiecko.stundenplanfhjena.Project;
import vu.alfonsodiecko.stundenplanfhjena.R;
import vu.alfonsodiecko.stundenplanfhjena.SQLiteHelper;
import vu.alfonsodiecko.stundenplanfhjena.SharedPreferencesHelper;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.widget.TextView;

public class SplashScreen extends Activity {
	private ProgressBar progress;
	private TextView text;
	private int state = 1;
	private Context context;
	// used to know if the back button was pressed in the splash screen activity
	// and avoid opening the next activity
	private boolean mIsBackButtonPressed;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.splash_screen);
		context = this.getApplicationContext();
		SharedPreferencesHelper sp = new SharedPreferencesHelper(context);
		String hash = sp.getSharedPreferences(Project.Strings.dbHash);

		if (hash.equals("") || !sp.getSharedPreferences(Project.Settings.autoUpdate).equals("true")) {

			update(hash);

		} else {
			sleepForSomeTime(3000, true);
		}

	}

	private void update(String oldHash) {
		progress = (ProgressBar) findViewById(R.id.progressBarLoad);
		text = (TextView) findViewById(R.id.textViewLoader);
		DownloadFileAsync task = new DownloadFileAsync();
		task.execute(Project.Websites.pathToDBHash, Project.Websites.pathToDB, oldHash);

	}

	private void sleepForSomeTime(int time, final boolean toTermin) {
		Handler handler = new Handler();
		handler.postDelayed(new Runnable() {
			@Override
			public void run() {
				// make sure we close the splash screen so the user won't come
				// back when it presses back key
				if (toTermin) {
					finish();
					if (!mIsBackButtonPressed) {
						// start the home screen if the back button wasn't
						// pressed
						// already
						Intent intent = new Intent(SplashScreen.this, TerminPlaner.class);
						SplashScreen.this.startActivity(intent);
					}
				}
			}
		}, time);
	}

	@Override
	public void onBackPressed() {

		// set the flag to true so the next activity won't start up
		mIsBackButtonPressed = true;
		super.onBackPressed();

	}

	class DownloadFileAsync extends AsyncTask<String, String, String> {

		@Override
		protected void onPreExecute() {
			text.setText("Suche nach Updates!");
			super.onPreExecute();

		}

		@Override
		protected String doInBackground(String... aurl) {
			int count;

			try {
				String newhash = OnlineHelper.getWebsite(new URL(aurl[0]), "UTF-8");
				if (newhash.equals(aurl[2])) {
					return null;
				}
				publishProgress("Update gefunden", "");
				URL url = new URL(aurl[1]);
				URLConnection conexion = url.openConnection();
				conexion.connect();

				int lenghtOfFile = conexion.getContentLength();

				InputStream input = new BufferedInputStream(url.openStream());
				// create if not exist
				File appDir = new File(Environment.getExternalStorageDirectory().getPath() + "/EAH_APP/");
				if (!appDir.exists()) {
					appDir.mkdir();

				}
				OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/EAH_APP/studiengang.zip");

				byte data[] = new byte[1024];

				long total = 0;

				while ((count = input.read(data)) != -1) {
					total += count;
					String[] progress = { "" + (int) ((total * 100) / lenghtOfFile) + "%", "Download " + lenghtOfFile / (1024 * 1000) + "mb " };
					publishProgress(progress);
					output.write(data, 0, count);
				}

				output.flush();
				output.close();
				input.close();
				publishProgress("Entpacke Datenbank", "");
				unpackZip(Environment.getExternalStorageDirectory().getPath() + "/EAH_APP/", "studiengang.zip");
				publishProgress("Kopiere Datenbank", "");
				SQLiteHelper db = null;
				try {

					SQLiteDatabase jht = null;
					db = new SQLiteHelper(context);
					// boolean isExist = db.isDataBaseExist();

					// get database, we will override it in next steep
					// but folders containing the database are created
					jht = db.getWritableDatabase();
					db.close();
					// copy database
					db.copyDataBase();
					jht.close();

				} catch (SQLException eSQL) {
					Log.e("log_tag", "Can not open database");
					return null;
				} catch (IOException IOe) {
					Log.e("log_tag", "Can not copy initial database");
					return null;
				} finally {
					SharedPreferencesHelper sp = new SharedPreferencesHelper(context);
					sp.setSharedPreferences(Project.Strings.dbHash, newhash);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;

		}

		private boolean unpackZip(String path, String zipname) {
			InputStream is;
			ZipInputStream zis;
			try {
				String filename;
				is = new FileInputStream(path + zipname);
				zis = new ZipInputStream(new BufferedInputStream(is));
				ZipEntry ze;
				byte[] buffer = new byte[1024];
				int count;

				while ((ze = zis.getNextEntry()) != null) {
					// zapis do souboru
					filename = ze.getName();

					// Need to create directories if not exists, or
					// it will generate an Exception...
					if (ze.isDirectory()) {
						File fmd = new File(path + filename);
						fmd.mkdirs();
						continue;
					}

					FileOutputStream fout = new FileOutputStream(path + filename);

					// cteni zipu a zapis
					while ((count = zis.read(buffer)) != -1) {
						fout.write(buffer, 0, count);

					}

					fout.close();
					zis.closeEntry();
				}

				zis.close();
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			}

			return true;
		}

		protected void onProgressUpdate(String... progress) {

			text.setText(String.valueOf(progress[1] + progress[0]));
		}

		@Override
		protected void onPostExecute(String unused) {

			sleepForSomeTime(2000, true);
		}
	}

}
